﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MapEntities;
using ServerPlatform.Web;
using ServerPlatform.Exceptions;

namespace WebApp.Controls
{
    public partial class MapDataEditor : BaseDataEditor<MapDataRequest>
    {
        protected override void OnInit(EventArgs e)
        {
            ScriptManager.GetCurrent(Page).AsyncPostBackError += new EventHandler<AsyncPostBackErrorEventArgs>(MapDataEditor_AsyncPostBackError);
            base.OnInit(e);            
        }

        void MapDataEditor_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
        {
            ApplicationException converted = ExceptionManager.Manage(e.Exception);
            if (converted is TechnicalException)
                ctlMessage.Text = "TECHNICAL ERROR: " + e.Exception.Message;
            else ctlMessage.Text = e.Exception.Message.Replace(Environment.NewLine, "<br />");
            HttpContext.Current.Server.ClearError();
            ScriptManager.GetCurrent(Page).AsyncPostBackErrorMessage = ctlMessage.Text;
            ctlMessagePanel.Update();

        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsCallback)
            {
                ctlMessage.Visible = false;
            }

        }

        private void showlayer(Layer l)
        {
            ctlLayerName.Text = l.Name;
            ctlLayerVisible.Checked = l.Visible;
            ctlZoomStart.Text = l.StartZoomLevel.ToString();
            ctlZoomEnd.Text = l.EndZoomLevel.ToString();
            ViewState["selectedLayerName"] = l.Name;
            ctlMapLayersRepeater.DataSource = Current.MapProperties.Layers;
            ctlMapLayersRepeater.DataBind();
        }

        public override void Edit(MapDataRequest item)
        {
            ctlTabContainer.ActiveTabIndex = 0;
            TabContainer1.ActiveTabIndex = 0;
            if (item.MapProperties.Layers.Count == 0)
            {
                Layer xnewlayer = new Layer();
                xnewlayer.Visible = true;
                xnewlayer.Name = "default";
                xnewlayer.StartZoomLevel = 0;
                xnewlayer.EndZoomLevel = 0;
                item.MapProperties.Layers.Add(xnewlayer);                
            }
            
            SaveEntity(item);                       
            if (item.ShapeBindingRuleDataList.Count > 0)
            {
                ViewState["selectedShapeBindingRuleId"] = item.ShapeBindingRuleDataList[0].ID;                
            }
            if (item.SymbolBindingRuleDataList.Count > 0)
            {
                ViewState["selectedSymbolBindingRuleId"] = item.SymbolBindingRuleDataList[0].ID;                
            }
            ShowEntity(item);
        }

        private bool SaveLayer(Layer xlayer)
        {
            if (Current.MapProperties.Layers.Exists(p => p.Name == ctlLayerName.Text.Trim()) && xlayer.Name != ctlLayerName.Text.Trim())
            {
                BusinessException ee = new BusinessException("This Layer Name already exists");
                throw ee;
            }
            try
            {
                xlayer.StartZoomLevel = int.Parse(ctlZoomStart.Text);
                xlayer.EndZoomLevel = int.Parse(ctlZoomEnd.Text);
            }
            catch (FormatException exc)
            {
                throw new BusinessException("Zoom Start and Zoom End must be integer", exc);
            }
            if (xlayer.StartZoomLevel < 0)
            {
                BusinessException ee = new BusinessException("Zoom Start Level must be greater than zero");
                throw ee;
            }
            if (xlayer.StartZoomLevel > xlayer.EndZoomLevel)
            {
                BusinessException ee = new BusinessException("Zoom End Level must be equal or greater than Zoom Start Level");
                throw ee;
            }
            xlayer.Name = ctlLayerName.Text.Trim();
            xlayer.Visible = ctlLayerVisible.Checked;
            return true;


        }
        protected void ctlSaveLayer_Click(object sender, EventArgs e)
        {
            if (ViewState["selectedLayerName"] != null)
            {
                int xindex  = Current.MapProperties.Layers.FindIndex(p => p.Name == ViewState["selectedLayerName"].ToString());
                Layer l = Current.MapProperties.Layers[xindex];
                if (l != null)
                {
                    if (SaveLayer(l))
                    {                       
                        Current.MapProperties.Layers[xindex] = l;
                        SaveEntity(Current);
                        showlayer(l);
                    }
                }
            }
            else
            {
                BusinessException ee = new BusinessException("Select a layer to save");
                throw ee;
            }

        }

        protected void ctlCreateLayer_Click(object sender, EventArgs e)
        {
            Layer newLayer = new Layer();
            if (SaveLayer(newLayer))
            {
                Current.MapProperties.Layers.Add(newLayer);
                SaveEntity();
                showlayer(newLayer);
            }
        }




        public override MapDataRequest EndEdit()
        {
            if (Page.IsValid)
            {
                MapDataRequest result = base.EndEdit();
                result.ShapeBindingRuleDataList = Current.ShapeBindingRuleDataList;
                result.SymbolBindingRuleDataList = Current.SymbolBindingRuleDataList;
               SilverlightMapProperties xsmp = ctlGeneralRuleEditor.EndEdit();  
                xsmp.Layers = result.MapProperties.Layers;
                result.MapProperties = xsmp;
                return result;
            }
            else return null;
        }


        protected override void ShowEntity(MapDataRequest entity)
        {
            ctlMapLayersRepeater.DataSource = entity.MapProperties.Layers;
            ctlMapLayersRepeater.DataBind();

            ctlShapeBindingRep.DataSource = entity.ShapeBindingRuleDataList;
            ctlShapeBindingRep.DataBind();

            ctlSymbolBindingRep.DataSource = entity.SymbolBindingRuleDataList;
            ctlSymbolBindingRep.DataBind();

            ShapeItemBindingRule xshaperule;
            SymbolItemBindingRule xsymbolrule;
            if (ViewState["selectedLayerName"] != null)
            {
                Layer xlayer = entity.MapProperties.Layers.First(p => p.Name == ViewState["selectedLayerName"].ToString().Trim());
                if (xlayer != null)
                {
                    showlayer(xlayer);
                }
                else showlayer(entity.MapProperties.Layers[0]);
            }
            else
            { 
                showlayer(entity.MapProperties.Layers[0]);
                ViewState["selectedLayerName"] = entity.MapProperties.Layers[0].Name;
            }

            if (ViewState["selectedShapeBindingRuleId"] != null && entity.ShapeBindingRuleDataList[new Guid(ViewState["selectedShapeBindingRuleId"].ToString())] != null)
            { xshaperule = entity.ShapeBindingRuleDataList[new Guid(ViewState["selectedShapeBindingRuleId"].ToString())]; }
            else { xshaperule = new ShapeItemBindingRule(); }
            if (ViewState["selectedSymbolBindingRuleId"] != null && entity.SymbolBindingRuleDataList[new Guid(ViewState["selectedSymbolBindingRuleId"].ToString())] != null)
            { xsymbolrule = entity.SymbolBindingRuleDataList[new Guid(ViewState["selectedSymbolBindingRuleId"].ToString())]; }
            else { xsymbolrule = new SymbolItemBindingRule(); }
            ctlShapes.Edit(xshaperule);
            ctlSymbols.Edit(xsymbolrule);
            ctlGeneralRuleEditor.Edit(Current.MapProperties);

        }

        public override MapDataRequest GetEntity()
        {            
            return Current;
        }

        protected void ctlMapLayersRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            Layer l = Current.MapProperties.Layers.SingleOrDefault(p => p.Name == e.CommandArgument.ToString());
            if (l != null)
            {
                if (e.CommandName == "selectLayer")
                {
                    showlayer(l);
                }
                else if (e.CommandName == "deleteLayer")
                {
                    if (Current.MapProperties.Layers.Count == 1)
                    {
                        BusinessException ee = new BusinessException("There must be at least one layer " + Environment.NewLine + "So you cannot delete this layer");
                        throw ee;
                    }
                    else
                    {
                        Current.MapProperties.Layers.Remove(l);
                        SaveEntity();
                        showlayer(Current.MapProperties.Layers[0]);
                    }
                }
            }
        }

        protected void ctlShapeBindingRep_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            ShapeItemBindingRule xrule = Current.ShapeBindingRuleDataList.SingleOrDefault(p => p.ID == new Guid(e.CommandArgument.ToString()));
            if (xrule != null)
            {
                if (e.CommandName == "selectShapeBinding")
                {
                    ctlShapes.Edit(xrule);
                    ViewState["selectedShapeBindingRuleId"] = e.CommandArgument;
                }
                else if (e.CommandName == "deleteShapeBinding")
                {
                    Current.ShapeBindingRuleDataList.Remove(xrule);
                    SaveEntity();
                    ViewState["selectedShapeBindingRuleId"] = null;
                    ShowEntity();
                }
            }
        }

        protected void ctlNewShape_Click(object sender, EventArgs e)
        {
            ctlShapes.ClearCurrent();
            ShapeItemBindingRule newRule = ctlShapes.EndEdit();
            ViewState["selectedShapeBindingRuleId"] = newRule.ID;
            Current.ShapeBindingRuleDataList.Add(newRule);
            SaveEntity();
            ShowEntity();
        }

        protected void ctlSaveShape_Click(object sender, EventArgs e)
        {
            ShapeItemBindingRule xrule = Current.ShapeBindingRuleDataList.SingleOrDefault(p => p.ID == new Guid(ViewState["selectedShapeBindingRuleId"].ToString()));
            ShapeItemBindingRule edited = ctlShapes.EndEdit();

            Current.ShapeBindingRuleDataList[new Guid(ViewState["selectedShapeBindingRuleId"].ToString())] = edited;

            xrule = edited;
            SaveEntity();
            ShowEntity();
        }

        protected void ctlNewSymbol_Click(object sender, EventArgs e)
        {
            ctlSymbols.ClearCurrent();
            SymbolItemBindingRule newRule = ctlSymbols.EndEdit();
            ViewState["selectedSymbolBindingRuleId"] = newRule.ID;
            Current.SymbolBindingRuleDataList.Add(newRule);
            SaveEntity();
            ShowEntity();
        }

        protected void ctlSymbolBindingRep_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            SymbolItemBindingRule xrule = Current.SymbolBindingRuleDataList.SingleOrDefault(p => p.ID == new Guid(e.CommandArgument.ToString()));
            if (xrule != null)
            {
                if (e.CommandName == "selectSymbolBinding")
                {
                    ctlSymbols.Edit(xrule);
                    ViewState["selectedSymbolBindingRuleId"] = e.CommandArgument;
                }
                else if (e.CommandName == "deleteSymbolBinding")
                {
                    Current.SymbolBindingRuleDataList.Remove(xrule);
                    SaveEntity();
                    ViewState["selectedSymbolBindingRuleId"] = null;
                    ShowEntity();
                }
            }
        }

        protected void ctlSaveSymbol_Click(object sender, EventArgs e)
        {
            SymbolItemBindingRule xrule = Current.SymbolBindingRuleDataList.SingleOrDefault(p => p.ID == new Guid(ViewState["selectedSymbolBindingRuleId"].ToString()));
            SymbolItemBindingRule edited = ctlSymbols.EndEdit();
            Current.SymbolBindingRuleDataList[new Guid(ViewState["selectedSymbolBindingRuleId"].ToString())] = edited;
            xrule = edited;
            SaveEntity();
            ShowEntity();
        }

        protected void ctlGeneralRuleSave_Click(object sender, EventArgs e)
        {
            Current.MapProperties = ctlGeneralRuleEditor.EndEdit();
            SaveEntity();
            ShowEntity();
        }



    }
}